﻿using System;
using System.Data.Services;
using System.Text;
using System.Web;
using System.Web.Security;

namespace umbraco.DataServices
{
    public static class ServiceAuthorization
    {
        public static void CheckAuthorization<T>(this DataService<T> dataService) {
            if (IsAuthorized(dataService) == false)
                Reauthenticate();
        }

        public static void Reauthenticate() {
            HttpContext.Current.Response.StatusCode = 401;
            HttpContext.Current.Response.Headers.Add("WWW-Authenticate", "Basic realm=\"Umbraco\"");
            HttpContext.Current.Response.End();
        }

        public static bool IsAuthorized<T>(this DataService<T> dataService) {
            //See If User Already Logged In The Backend
            if (BusinessLogic.User.GetCurrent() != null)
                return true;

            var header = HttpContext.Current.Request.Headers["Authorization"];
            if (string.IsNullOrEmpty(header) || header.StartsWith("Basic", StringComparison.InvariantCulture) == false) {
                return false;
            }

            //Check Authorization Header
            var basicAuth = header.Remove(0, 6); //Remove Basic
            var base64 = Convert.FromBase64String(basicAuth);
            if (base64 == null) {
                return false;
            }

            //Decode Base64
            var plainTextAuth = Encoding.ASCII.GetString(base64);
            if (plainTextAuth.Contains(":") == false) {
                return false;
            }

            var plainTextAuthSplit = plainTextAuth.Split(Convert.ToChar(":"));
            var userName = plainTextAuthSplit[0];
            var passWord = plainTextAuthSplit[1];

            try
            {
                //Use Membership Provider To 
                if (Membership.Providers[UmbracoSettings.DefaultBackofficeProvider].ValidateUser(userName, passWord))
                    return true;
            } catch (Exception ex) {}

            return false;
        }
    }
}
